from selenium import webdriver
from PIL import ImageGrab
import time
from selenium.webdriver.common.keys import Keys
import json
import smtplib
import datetime
import random
import base64
import os
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
################################################################全局变量#################################################
jsonPath = "config/config.json"
logPath = "config/log.txt"
driverPath = "config/chromedriver.exe"
################################################################发送邮件记录日志#################################################
def sendMessage(receiver,text,picPathResule,picPathForm):
    "发送邮件的函数，参数1：接收方邮箱，参数2：类型，0：体温填写成功，体温填写失败"
    with open(jsonPath, 'r', encoding='utf8') as config:
        json_data = json.load(config)
    msg_from = json_data["conf"]["qqSender"]  # 发送方邮箱
    passwd = json_data["conf"]["authorizationCode"]  # 填入发送方邮箱的授权码
    msg_to = receiver  # 收件人邮箱
    subject = text  # 主题
    if picPathForm != "" and picPathResule != "":#如果两个截图都有
        content = MIMEText('<html><body><p><img src="cid:imageid1" alt="imageid"></p><p><img src="cid:imageid2" alt="imageid2"></p></body></html>', 'html', 'utf-8')  # 正文
        msg = MIMEMultipart('related')
    elif picPathForm != "" and picPathResule == "": #只有过程截图
        content = MIMEText('<html><body><p><img src="cid:imageid2" alt="imageid2"></p></body></html>','html', 'utf-8')  # 正文
        msg = MIMEMultipart('related')
    else:#两个截图都没有,只文本提示
        content = MIMEText('<html><body><p>'+text+'</p></body></html>', 'html', 'utf-8')
        msg = MIMEMultipart('related')
    msg.attach(content)
    msg['Subject'] = subject
    msg['From'] = msg_from
    msg['To'] = msg_to
    if picPathResule != "":
        fileResult = open(picPathResule,"rb")
        img_dataResult = fileResult.read()
        fileResult.close()
        imgResult = MIMEImage(img_dataResult)
        imgResult.add_header('Content-ID', 'imageid1')
        msg.attach(imgResult)
    if picPathForm != "":
        fileForm = open(picPathForm,"rb")
        img_dataForm = fileForm.read()
        fileForm.close()
        imgForm = MIMEImage(img_dataForm)
        imgForm.add_header('Content-ID', 'imageid2')
        msg.attach(imgForm)
    try:
        s = smtplib.SMTP_SSL("smtp.qq.com", 465)  # 邮件服务器及端口号
        s.login(msg_from, passwd)
        s.sendmail(msg_from, msg_to, msg.as_string())
        print(text)
    except Exception as e:
        pass
        print(e)
        print(text)
def log(username,result):
    "记录日志的函数，参数1：用户，参数2：填写结果：成功或失败"
    with open(logPath, "a", encoding="utf-8") as log:
        curr_time = datetime.datetime.now()
        text = "\n"+datetime.datetime.strftime(curr_time,'%Y-%m-%d %H:%M:%S')+"\n账号：" + username +"  结果："+ result
        log.write(text)
        log.close()
def logTime():
    "打印时间"
    with open(logPath, "a", encoding="utf-8") as log:
        curr_time = datetime.datetime.now()
        text = "\n"+"=============================="+datetime.datetime.strftime(curr_time,'%Y-%m-%d %H:%M:%S')+"=============================="+"\n"
        log.write(text)
def logResult(correctNum,actuallyNum):
    "打印统计结果,如果实际运行结果与本应运行结果不一致,那么发送邮件"
    if (correctNum!=actuallyNum):
        sendMessage("798940311@qq.com","体温脚本出现了异常,请检查!!!","","")
    with open(logPath, "a", encoding="utf-8") as log:
        text = "\n"+"==============================运行结果=============================="+"\n"+"应该成功运行的次数---->"+str(correctNum)+"\n"+"实际运行的次数---->"+str(actuallyNum)+"\n"
        log.write(text)

################################################################元素是否存在判断函数#################################################
def ifElementExistByXpath(browser,xpath):
    "根据xpath判断元素是否存在"
    try:
        browser.find_element_by_xpath(xpath)
        return True
    except Exception as e:
        return False
def ifElementExistByClassName(browser,className):
    "根据classname判断元素是否存在"
    try:
        browser.find_element_by_class_name(className)
        return True
    except Exception as e:
        return False
################################################################时间处理函数#################################################
def CutHour(time=datetime.datetime.now()):
    """截取时分秒"""
    new_time = str(time)
    hour = new_time[11:19]
    return "".join(hour)
def conversion_strTotime(str):
    hour = int(str[0:2])*3600
    min = int(str[3:5])*60
    second = int(str[6:8])
    return hour+min+second
def comp_time(now_time,begin_time):
    time1 = conversion_strTotime(now_time)
    time2 = conversion_strTotime(begin_time)
    return time1-time2
def getTimeCompare(time="11:30:00"):
    return comp_time(CutHour(), CutHour(datetime.datetime.strptime(time, '%H:%M:%S')))
################################################################其他函数#################################################
def getTemperature():
    "获取随机温度"
    tem = round(random.random() + 36.0, 1)
    return tem
def getScreen(picPath):
    "全屏截图,这个暂时不用"
    fileName = picPath+str(time.time())+".jpg"
    ImageGrab.grab().save(fileName)
    return fileName
def getLongScreen(picPath,browser):
    "网页长截图"
    fileName = picPath + str(time.time()) + ".jpg"
    # 取出页面的宽度和高度
    page_width = browser.execute_script("return document.body.scrollWidth")
    page_height = browser.execute_script("return document.body.scrollHeight")

    # 直接开启设备模拟，不要再手动开devtools了，否则截图截的是devtools的界面！
    browser.execute_cdp_cmd('Emulation.setDeviceMetricsOverride',{'mobile': False, 'width': page_width, 'height': page_height, 'deviceScaleFactor': 1})

    # 执行截图
    res = browser.execute_cdp_cmd('Page.captureScreenshot', {'fromSurface': True})
    with open(fileName, 'wb') as f:
        img = base64.b64decode(res['data'])
        f.write(img)
    browser.execute_cdp_cmd('Emulation.clearDeviceMetricsOverride', {})
    return fileName
def Delete_File(path):
    "删除文件夹所有子文件"
    for i in os.listdir(path):
       path_file = os.path.join(path,i)
       if os.path.isfile(path_file):
           os.remove(path_file)
       else:
         for f in os.listdir(path_file):
             path_file2 =os.path.join(path_file,f)
             if os.path.isfile(path_file2):
                 os.remove(path_file2)
#####################################################填写表格函数############################################################
def fillTemperature(browser,username,password,receiver,picPath):
    "填写体温，参数1：用户名，参数2：密码,参数3：接收者邮箱"
    try:
        picPathResule = ""
        picPathForm = ""
        browser.get("http://xscfw.hebust.edu.cn/survey/login")
        browser.find_element_by_id("user").send_keys(username)  # 账号
        browser.find_element_by_id("pwd").send_keys(password)  # 密码
        time.sleep(1)
        browser.find_element_by_id("login").click()
        time.sleep(1)
        #判断是否已经填写,已经填写将不再填写
        if ifElementExistByXpath(browser, "/html/body/ul/li[1]/div/span"):
            ifSuccess = browser.find_element_by_xpath("/html/body/ul/li[1]/div/span").text
            if ifSuccess == "已完成":
                log(username, "已经填写!!")  # 记录日志
                sendMessage(receiver, "您已填写!!", picPathResule, picPathForm)
                return
        if ifElementExistByClassName(browser,"mdui-list-item-content"):
            browser.find_element_by_class_name("mdui-list-item-content").click()  # 进入填写页面
            time.sleep(1)
        else:
            log(username, "体温填写失败,账号密码不正确或体温系统未开放!!!")  # 记录日志
            sendMessage(receiver,"体温填写失败,账号密码不正确或体温系统未开放!!!",picPathResule,picPathForm)
            return
        if ifElementExistByXpath(browser,"//*[@name='c0'and @option='0']/parent::*"):######################晨检体温
            browser.find_element_by_xpath("//*[@name='c0'and @option='0']/parent::*").click()
        if ifElementExistByXpath(browser,"//*[@name='c1']"):
            browser.find_element_by_xpath("//*[@name='c1']").send_keys(Keys.CONTROL, 'a')
            zs_tem = str(getTemperature())
            browser.find_element_by_xpath("//*[@name='c1']").send_keys(zs_tem)  #####晨检体温
        if ifElementExistByXpath(browser,"//*[@name='c3'and @option='0']/parent::*"):
            browser.find_element_by_xpath("//*[@name='c3'and @option='0']/parent::*").click()##############午检体温
        if ifElementExistByXpath(browser,"//*[@name='c4']"):
            browser.find_element_by_xpath("//*[@name='c4']").send_keys(Keys.CONTROL, 'a')
            zw_tem = str(getTemperature())
            browser.find_element_by_xpath("//*[@name='c4']").send_keys(zw_tem)#######午检体温
        if ifElementExistByXpath(browser,"//*[@name='c6'and @option='0']/parent::*"):
            browser.find_element_by_xpath("//*[@name='c6'and @option='0']/parent::*").click()############今日健康状况是
        #将填写结果截图
        picPathForm = getLongScreen(picPath,browser)
        if ifElementExistByXpath(browser,"//*[@id='save']"):
            browser.find_element_by_xpath("//*[@id='save']").click()  ################################## 提交
        time.sleep(1)

        now_url = browser.current_url#获取页面的url

        if now_url=="http://xscfw.hebust.edu.cn/survey/index.action":
            ifSuccess = ""
            if ifElementExistByXpath(browser, "/html/body/ul/li[1]/div/span"):
                ifSuccess = browser.find_element_by_xpath("/html/body/ul/li[1]/div/span").text
            else:
                log(username, "填写失败")  # 记录日志
                sendMessage(receiver, "体温填写失败,请手动填写", picPathResule, picPathForm)
            if ifSuccess == "已完成":
                # 截图
                picPathResule = getLongScreen(picPath, browser)
                log(username,"填写成功")#记录日志
                sendMessage(receiver, "体温填写成功", picPathResule,picPathForm)
                time.sleep(1)
            else:
                log(username, "填写失败")  # 记录日志
                sendMessage(receiver, "体温填写失败,请手动填写", picPathResule, picPathForm)
        else:
            log(username,"体温填写失败，表格有新加内容")
            sendMessage(receiver, "体温填写!!!!!失败!!!!!表格有新加内容", picPathResule,picPathForm)
            time.sleep(1)
    except Exception as e:
        log(username, "填写失败\n"+e)
        sendMessage(receiver, "体温填写失败!!!", picPathResule,picPathForm)
        print(e)
        pass

#####################################################主函数############################################################
def run():
    "主函数"
    with open(jsonPath, 'r', encoding='utf8') as config:
        json_data = json.load(config)
    browser = webdriver.Chrome(driverPath)
    logTime()#打印一下时间
    i = 0
    while i<len(json_data['info']):
        fillTemperature(browser,json_data["info"][i][0],json_data["info"][i][1],json_data["info"][i][2],json_data['conf']['picPath'])
        i = i+1
    browser.close()
    logResult(len(json_data['info']), i)#运行结果记录
    Delete_File(json_data['conf']['picPath'])#运行结束后删除所有图片

if __name__ == "__main__":
    try:
         run()
    except Exception as e:
        print(e)
        pass